package com.yzr.common.thread;

public class MyThread {

    /**
     * 线程也可以唤醒，而不会被通知，中断或超时，即所谓的虚假唤醒 。
     * 虽然这在实践中很少会发生，但应用程序必须通过测试应该使线程被唤醒的条件来防范，
     * 并且如果条件不满足则继续等待。 换句话说，等待应该总是出现在循环中，就像这样：
     * <p>
     * synchronized (obj) {
     * while (<condition does not hold>)
     * obj.wait(timeout);
     * ... // Perform action appropriate to condition
     * }
     *
     * @param args
     */
    public static void main(String[] args) {

        ThreadSource threadSource = new ThreadSource();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    threadSource.addition();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    threadSource.subtraction();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    threadSource.addition();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "C").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    threadSource.subtraction();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "D").start();
    }
}

class ThreadSource {
    private Integer num = 0;

    public synchronized void addition() throws InterruptedException {
        while (num != 0) {
            this.wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName() + "--->" + num);
        this.notifyAll();
    }

    public synchronized void subtraction() throws InterruptedException {
        while (num == 0) {
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName() + "--->" + num);
        this.notifyAll();
    }
}